package com.lincoln.service;

import com.lincoln.entity.permission.DbPermission;
import com.lincoln.entity.permission.DbUserPermission;
import com.lincoln.entity.user.DbUser;
import com.lincoln.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Exception.class)
public class UserService extends BaseService<DbUser, UserRepository> {
    @Autowired
    UserPermissionService userPermissionService;

    /**
     * 建立分页排序请求
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public PageRequest buildPageRequest(int pageNo, int pageSize, Sort.Order... orders) {
        Sort sort = Sort.by(orders);
        return PageRequest.of(pageNo, pageSize, sort);
    }

    @Override
    public Predicate createPredicate(Root<DbUser> root, CriteriaBuilder cb, Map<String, Object> params) {
        Predicate result = cb.and();
        if (params.get("username") != null) {
            Predicate p = cb.like(root.get("username").as(String.class), "%" + params.get("username") + "%");
            result = cb.and(result, p);
        }
        if (params.get("password") != null) {
            Predicate p = cb.equal(root.get("password").as(String.class), params.get("password"));
            result = cb.and(result, p);
        }
        if (params.get("roleId") != null) {
            Predicate p = cb.equal(root.get("role").get("id").as(Long.class), params.get("roleId"));
            result = cb.and(result, p);
        }
        return result;
    }

    /**
     * 通过用户名/id查询用户
     *
     * @param idOrName
     * @return
     */
    public DbUser findByIdOrName(String idOrName) {
        DbUser user = null;
        try {
            long id = Long.parseLong(idOrName);
            user = findById(id);
            if (user == null) {
                throw new Exception("可能不是id,在这抛个异常让下面catch");
            }
        } catch (Exception e) {
            user = findByUniqueForOne("userName", idOrName);
        }
        return user;
    }

    /**
     * 通过用户名查询用户
     *
     * @param userName
     * @return
     */
    public DbUser findByUserName(String userName) {
        try {
            List<DbUser> list = findByUnique("userName", userName);
            if (list == null || list.size() <= 0) {
                return null;
            }
            return list.get(0);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取一个用户实际的权限(通过循环计算得到)
     *
     * @return
     */
    public List<DbPermission> findPermissions(String idOrName) {
        DbUser user = findByIdOrName(idOrName);
        if (user == null) {
            return new ArrayList<>();
        }
        return findPermissions(user);
    }

    /**
     * 获取一个用户实际的权限(通过循环计算得到)
     *
     * @param user 确保是最新的数据
     * @return
     */
    public List<DbPermission> findPermissions(DbUser user) {
        if (user == null) {
            return new ArrayList<>();
        }
        List<DbPermission> result = new ArrayList<>();
        List<DbUserPermission> whites = userPermissionService.findUserWhitePermission(user.getId());
        List<DbUserPermission> blacks = userPermissionService.findUserBlackPermission(user.getId());
        user.getRole().getPermissions().forEach(p -> {
            result.add(p);
        });
        blacks.forEach(p -> {
            result.remove(p.getPermission());
        });
        whites.forEach(p -> {
            result.add(p.getPermission());
        });
        return result;
    }
}
